home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / softwareupdate / system / amigados / advancedroutines / example7.c < prev    next >
C/C++ Source or Header  |  1996-10-10  |  11KB  |  299 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE)           Amiga C Club (ACC) */
  4. /* --------------------------           ------------------ */
  5. /*                                                         */
  6. /* Manual:  AmigaDOS                    Amiga C Club       */
  7. /* Chapter: Advanced Routines           Tulevagen 22       */
  8. /* File:    Example7.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    93-03-17                                       */
  11. /* Version: 1.1                                            */
  12. /*                                                         */
  13. /*   Copyright 1993, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20. /* This example will as the previous one examine the special */
  21. /* lists of available Assigns, Volumes and Devices. This     */
  22. /* example will however add the volume name to the device    */
  23. /* in which the volume is. We will also only print the       */
  24. /* devices (with their volume name) which are currently      */
  25. /* available to access. We will for example not print the    */
  26. /* device "df0:" if there is not a disk in that drive.       */
  27. /* However, if there is a disk in the drive we will both     */
  28. /* print the device name and the name of the volume which is */
  29. /* in that device. We will therefore get a list which is     */
  30. /* identical to the one used by the ASL file requeter.       */
  31.  
  32.  
  33.  
  34. /* Include the dos library definitions: */
  35. #include <dos/dos.h>
  36.  
  37. /* Include memory definitions: (MEMF_ANY...) */
  38. #include <exec/memory.h>
  39.  
  40. /* Now we include the necessary function prototype files:         */
  41. #include <clib/dos_protos.h>       /* General dos functions...    */
  42. #include <clib/exec_protos.h>      /* System functions...         */
  43. #include <stdio.h>                 /* Std functions [printf()...] */
  44. #include <stdlib.h>                /* Std functions [exit()...]   */
  45.  
  46.  
  47.  
  48. /* Set name and version number: */
  49. UBYTE *version = "$VER: AmigaDOS/Advanced Routines/Example7 1.1";
  50.  
  51.  
  52.  
  53. /* 1. Declare an external global library */
  54. /*    pointer to the Dos library:        */
  55. extern struct DosLibrary *DOSBase;
  56.  
  57.  
  58.  
  59. /* Declare our own functions: */
  60.  
  61. /* Our main function: */
  62. int main( int argc, char *argv[] );
  63.  
  64. /* Prints the device name of a volume: */
  65. int PrintDevice( struct DosList *first_node, APTR task );
  66.  
  67. /* Prints BCPL strings: */
  68. void PrintBSTR( BSTR string_bstr, int total_length );
  69.  
  70.  
  71.  
  72. /* Main function: */
  73.  
  74. int main( int argc, char *argv[] )
  75. {
  76.   /* Temporary BCPL pointer used to convert BPTRs into C pointer: */
  77.   BPTR temp_bptr;
  78.  
  79.   /* Pointer to the RootNode structure: */
  80.   struct RootNode *rootnode_ptr;
  81.  
  82.   /* Pointer to a DosInfo structure: */
  83.   struct DosInfo *dos_info_ptr;
  84.  
  85.   /* Pointer to the first DosList structure: */
  86.   struct DosList *first_doslist_node;
  87.  
  88.   /* Pointer to the current (the one we are */
  89.   /* working with) DosList structure:       */
  90.   struct DosList *doslist_node;
  91.   
  92.   
  93.   
  94.  
  95.   /* 2. Get a pointer to the RootNode structure: */
  96.   rootnode_ptr = DOSBase->dl_Root;
  97.  
  98.   /* 3. Get a BCPL pointer (BPTR) to the DosInfo structure: */
  99.   temp_bptr = rootnode_ptr->rn_Info;
  100.  
  101.   /* 4. Convert the BCPL pointer into a normal C pointer: */
  102.   /* (If I say that I hate BCPL with its acquired      */
  103.   /* pointers and strings I do not exaggerate...)      */
  104.   dos_info_ptr = (struct DosInfo *) BADDR( temp_bptr );
  105.  
  106.  
  107.  
  108.   /* Before we may start to examine the DosInfo structure we    */
  109.   /* have to turn off the multitasking by calling the Forbid()  */
  110.   /* function. As soon as we have finished using the DosInfo    */
  111.   /* structure we must of course turn the multitaskin on again, */
  112.   /* by calling the Permit() function.                          */
  113.   /*                                                            */
  114.   /* Note that while the multitasking is OFF we must be very    */
  115.   /* careful so we do not try to wait for some external event.  */
  116.   /* If we try to wait for something to happen "outside" our    */
  117.   /* program we will sit and wait forever since nothing can     */
  118.   /* happen outside our program as long as the multitasking is  */
  119.   /* off. You must therefore NEVER use the Wait() or similar    */
  120.   /* functions after you have forbidden other programs to run.  */
  121.   /* As soon as we turn the multitasking on again, by using the */
  122.   /* Permit() function, we may of course start to wait for      */
  123.   /* external events.                                           */
  124.   /*                                                            */
  125.   /* A program that turns off the multitasking is interrupting  */
  126.   /* other programs. You must therefore try to turn the         */
  127.   /* multitaskin on again as soon as possible.                  */
  128.   /*                                                            */
  129.   /* With the new Release 2 you should actually use the special */
  130.   /* LockDosList() and NextDosEntry() functions instead of      */
  131.   /* using the Forbid() and Permit() functions. However, since  */
  132.   /* this program should run on all Amigas we stick to the old  */
  133.   /* methods. (See "Amiga DOS" chapter for more information on  */
  134.   /* the new LockDosList() and NextDosEntry() functions.)       */
  135.  
  136.   /* 5. Turn the multitaskin OFF: */
  137.   Forbid(); 
  138.  
  139.  
  140.  
  141.   /* 6. Scan the "DosList" nodes... */
  142.  
  143.   /* Get a BCPL pointer (BPTR) to the first "DosList" node: */
  144.   temp_bptr = dos_info_ptr->di_DevInfo;
  145.  
  146.   /* Convert the BPTR into a C pointer: */
  147.   first_doslist_node = (struct DosList *) BADDR( temp_bptr );
  148.  
  149.   /* Start with the first node: */
  150.   doslist_node = first_doslist_node;
  151.  
  152.   /* Check all nodes: */
  153.   while( doslist_node )
  154.   {
  155.     /* There exist three different types of objects we can find:    */
  156.     /*   1. Devices (the "hardware parts") like the disk drives     */
  157.     /*      "df0:", "df1:"..., possible harddisks "hd0:"...,        */
  158.     /*      as well as all the special devices like "PRT:", "SER:", */
  159.     /*      "CON:" etc...                                           */
  160.     /*                                                              */
  161.     /*   2. Volumes, which is the name of the different objects     */
  162.     /*      (the name of the disks e.g. "ACE1:", name of the hard   */
  163.     /*      disk partitions "HD0:", "HD1:" etc...) Each of these    */
  164.     /*      volumes must be in one of the Devices! The "ACE" disk   */
  165.     /*      is maybe in "df0:", and hard disk "HD0:" probably in    */
  166.     /*      device "DH0:" and so on...                              */
  167.     /*                                                              */
  168.     /*   3. Assigns, simle assigns created with help of the Shell   */
  169.     /*      command "Assign".                                       */
  170.     /*                                                              */
  171.     /* Since we only want to print the device names in which there  */
  172.     /* is a volume, we only print the volume names and will then    */
  173.     /* look up the device which the volume is in. Assigns we print  */
  174.     /* directly.                                                    */
  175.  
  176.     /* Is it a volume? */
  177.     if( doslist_node->dol_Type == DLT_VOLUME )
  178.     {
  179.       /* We have found a volume! Print the name of the */
  180.       /* device in which the volume is:                */
  181.       if( PrintDevice( first_doslist_node,
  182.                        (APTR) doslist_node->dol_Task ) != RETURN_OK )
  183.         printf( "Could not find the volume's device name!" );
  184.       else
  185.         PrintBSTR( doslist_node->dol_Name, 30 );
  186.  
  187.       printf ( "\n" );
  188.     }
  189.  
  190.     /* Is it an Assign? */
  191.     if( doslist_node->dol_Type == DLT_DIRECTORY )
  192.     {
  193.       /* It is an Assigs! Simply print the string "<ASN>" and */
  194.       /* add the assign name:                                 */
  195.       printf( "<ASN>   " );
  196.       PrintBSTR( doslist_node->dol_Name, 30 );
  197.       printf ( "\n" );
  198.     }
  199.  
  200.  
  201.     /* Get a BPTR to the next node and convert the BPTR */
  202.     /* into a C pointer:                                */
  203.     doslist_node = (struct DosList *) BADDR( doslist_node->dol_Next );
  204.   }
  205.  
  206.   /* 7. Turn the multitaskin ON again: */
  207.   Permit();
  208. }
  209.  
  210.  
  211.  
  212. /* Prints the device name of a volume: (With help of the  */
  213. /* address to the "task" which handles our volume we can  */
  214. /* find the corresponding device. Both the device and the */
  215. /* volume use the same "task" if the volume is in the     */
  216. /* device.)                                               */
  217. int PrintDevice
  218. (
  219.   struct DosList *first_node,
  220.   APTR task
  221. )
  222. {
  223.   /* Node pointer: */
  224.   struct DosList *node;
  225.  
  226.  
  227.  
  228.   /* Start with the first node: (Rescan the whole list!) */
  229.   node = first_node;
  230.  
  231.   /* Check all nodes: */
  232.   while( node )
  233.   {
  234.     /* Check all devices: */
  235.     if( node->dol_Type == DLT_DEVICE )
  236.     {
  237.       /* Has the device a pointer to the same task */
  238.       /* as the volume which we are examining?     */
  239.       if( task == (APTR) node->dol_Task )
  240.       {
  241.         /* Found it! Print the device name: */
  242.         PrintBSTR( node->dol_Name, 8 );
  243.         
  244.         /* Return with the satisfaction of a job well done... */
  245.         return( RETURN_OK );
  246.       }
  247.     }
  248.     
  249.     /* Convert the next node's BPTR into a C pointer: */
  250.     node = (struct DosList *) BADDR( node->dol_Next );
  251.   }
  252.   
  253.   /* Ooops, something is wrong here. Could not find */
  254.   /* the volume's corresponding device name...      */
  255.   return( RETURN_ERROR );
  256. }
  257.  
  258.  
  259.  
  260. /* Handly little function which prints BCPL strings (BSTRs): */
  261. /* (This one will add any necessary spaces to fill the whole */
  262. /* "total_length" with text. This makes it look better since */
  263. /* we can now use nice columns of text.)                     */
  264.  
  265. void PrintBSTR
  266. (
  267.   BSTR string_bstr,
  268.   int total_length
  269. )
  270. {
  271.   /* Temporary string pointer */
  272.   UBYTE *string_ptr;
  273.  
  274.   /* The length of the BCPL string: */
  275.   UBYTE length;
  276.  
  277.   /* Simple loop variable: */
  278.   int loop;
  279.  
  280.   
  281.   
  282.   /* Conver the BSTR into a normal C pointer to a BCPL string: */
  283.   string_ptr = (UBYTE *) BADDR( string_bstr );
  284.  
  285.   /* Get the length of the BCPL string: (A BCPL string does not */
  286.   /* contain a NULL sign in the end, but uses instead the first */
  287.   /* byte to tell how many characters the string contains. A    */
  288.   /* BCPL string (BSTR) can therefore not contain more than 255 */
  289.   /* characters.                                                */
  290.   length = string_ptr[ 0 ];
  291.  
  292.   /* Print BCPL string: */
  293.   for( loop=1; loop <= total_length; loop++ )
  294.     if( loop <= length )
  295.       putchar( string_ptr[ loop ] );
  296.     else
  297.       putchar( ' ' );
  298. }
  299.